package com.lgl.scs.userIndex.controller;

import com.github.pagehelper.PageInfo;
import com.lgl.scs.base.controller.BaseController;
import com.lgl.scs.information.service.AddressService;
import com.lgl.scs.userIndex.service.ServiceOrderService;
import com.lgl.scs.util.utils.ControllerUtil;
import com.lgl.scsapi.system.model.AppUser;
import com.lgl.scsapi.system.model.PageData;
import com.lgl.scsapi.system.model.ServiceOrder;
import com.lgl.scsapi.util.utils.BillNumberTool;
import com.lgl.scsapi.util.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 订单controller
 * 注：后期要防止同一人抢太多的未完成订单
 */
@Slf4j
@RestController
@RequestMapping(value="/serviceOrder")
public class ServiceOrderController extends BaseController{
	@Resource(name="serviceOrderService")
	private ServiceOrderService serviceOrderService;
	@Resource(name="addressService")
	private AddressService addressService;
    //@Resource
    //private RedisTemplate redisTemplate;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
	
	//保存服务订单
	@RequestMapping(value="/saveServiceOrder", produces="application/json;charset=UTF-8")
	public Object saveServiceOrder(ServiceOrder serviceOrder) {
		PageData resultMap = new PageData(4);
		AppUser appUser = this.getSessionAppUser();
		boolean isSuccess = false;
		String soCityCode = serviceOrder.getSoCityCode();
        if (!StringUtils.hasText(serviceOrder.getSoName()) || !StringUtils.hasText(serviceOrder.getSoPhone())) {
            return returnPageData(resultMap, false, "4");
        }
        //获取城市编码
		if (!StringUtils.hasText(soCityCode)){
            soCityCode = ControllerUtil.getCityCodeByName(serviceOrder,addressService);
			//如果没获取到城市编码，则直接返回失败
			if (!StringUtils.hasText(soCityCode)){
				return returnPageData(resultMap, false,"3");
			}
            serviceOrder.setSoCityCode(soCityCode);
		}

        PageData pd = this.getPageData();
        String serviceDate = pd.getString("serviceDate"),//获取服务时间
                cityAreaName = pd.getString("cityArea");//城市下的区县名
        if (!StringUtils.hasText(serviceDate) || !DateUtil.isValidDate(serviceDate)) {
            return returnPageData(resultMap, false, "2");
        }
		if (!StringUtils.hasText(serviceOrder.getSoAreaCode())){
			serviceOrder.setSoAreaCode(getAreaCode(pd,cityAreaName,soCityCode));
		}
        serviceOrder.setSoServiceDate(serviceDate);
        serviceOrder.setSoUserId(appUser.getUserId());
        //serviceOrder.setSoHtmlPath(Constants.HTML_PATH.split("html/")[1]);
        //订单号目前的规则是：1位客户端来源(0，1：PC，2，3，4：微信，5，6，7：安卓，8，9：IOS)+月日+4位随机码
        String clientNo = serviceOrder.getSoBillNumber();
        String billNo = BillNumberTool.getBillNo(clientNo, stringRedisTemplate);
        serviceOrder.setSoBillNumber(clientNo + billNo);
        try {
            isSuccess = serviceOrderService.saveServiceOrder(serviceOrder);
        } catch (Exception e) {
            log.error("生成订单报错了", e);
            String errorMsg = e.getMessage();
            //如果错误信息中包含“UQ_ORDER_BILLNO”，则说明是单号重复了，重新生成单号
            if (errorMsg.contains("UQ_ORDER_BILLNO")) {
                isSuccess = retrySaveOrder(clientNo, billNo, serviceOrder);
            }
        }
        resultMap.clear();
		return returnPageData(resultMap, isSuccess, isSuccess ? "0" : "1");
	}

	/**
	 * 获取区/县编码
	 * @param cityAreaPd 城市区县相关参数
	 * @param areaName 区/县名称
	 * @param cityCode 城市编码
	 * @return 区/县编码
	 */
	private String getAreaCode(PageData cityAreaPd, String areaName,String cityCode){
		String areaCode = null;
		List<PageData> areaList = null;
		//通过区域名称获取区域编码
		if (StringUtils.hasText(areaName)) {
			cityAreaPd.clear();
			cityAreaPd.put("areaName", areaName);
			areaList = addressService.listAllArea(cityAreaPd);
		}
		//从缓存取城市下的区县信息
		//List<PageData> areaList = EhcacheUtil.getInstance().forCacheGetAreaByCityId(cityCode);//从缓存中取
		if (areaList == null || areaList.isEmpty()) {
			cityAreaPd.clear();
			cityAreaPd.put("cityCode", cityCode);
			areaList = addressService.listAllArea(cityAreaPd);
		} else if (areaList.size() == 1) {
			areaCode = areaList.get(0).getString("areaCode");
		}
		//获取区县编码
		if (!StringUtils.hasText(areaCode)) {
			for (int i = 0; i < areaList.size(); i++) {
				PageData areaPd = areaList.get(i);
				if (areaName.equals(areaPd.getString("areaName"))) {
					return areaPd.getString("areaCode");
				}
			}
		}
		return areaCode;
	}
    /**
     * 重试保存订单
     *
     * @param clientNo     客户编码
     * @param billNo       订单号
     * @param serviceOrder 订单对象
     * @return true：成功,false: 失败
     */
    private boolean retrySaveOrder(String clientNo, String billNo, ServiceOrder serviceOrder) {
        boolean isSuccess = true;
        if ("0".equals(clientNo)) {
            clientNo = "1";
        } else if ("1".equals(clientNo)) {
            clientNo = "0";
        } else if ("2".equals(clientNo)) {
            clientNo = "3";
        } else if ("3".equals(clientNo)) {
            clientNo = "4";
        } else if ("4".equals(clientNo)) {
            clientNo = "2";
        }
        try {
            serviceOrder.setSoBillNumber(clientNo + billNo);
            isSuccess = serviceOrderService.saveServiceOrder(serviceOrder);
        } catch (Exception e) {
            log.error("重试保存订单报错了", e);
            String errorMsg = e.getMessage();
            //如果错误信息中包含“UQ_ORDER_BILLNO”，则说明是单号重复了，重新生成单号
            if (errorMsg.contains("UQ_ORDER_BILLNO")) {
                serviceOrder.setSoBillNumber(clientNo + BillNumberTool.getBillNo(clientNo, stringRedisTemplate));
                isSuccess = serviceOrderService.saveServiceOrder(serviceOrder);
            }
        }
        return isSuccess;
    }
	//抢服务订单
	@RequestMapping(value="/robServiceOrder", produces="application/json;charset=UTF-8")
	public Object robServiceOrder() {
		PageData resultMap = this.getPageData();
		AppUser appUser = this.getSessionAppUser();
		String soBillNumber = resultMap.getString("billNumber");
		//订单号不存在
		if (!StringUtils.hasText(soBillNumber)){
			return returnPageData(resultMap, false, "3");
		}
		try {
			ServiceOrder serviceOrder = serviceOrderService.getServiceOrderByBillNumber(resultMap);
			//服务订单不存在
			if (serviceOrder == null){
				return returnPageData(resultMap, false, "3");
			}
			//服务订单已抢
			if (serviceOrder.getSoStatus() != 0){
				return returnPageData(resultMap, false, "4");
			}
			AppUser robber = getSessionAppUser();
			if (robber.getUserId().equals(serviceOrder.getSoUserId())){
				return returnPageData(resultMap, false, "5");
			}
			//如果订单存在，并且还没被抢
			resultMap.put("soStatus", "1");
			resultMap.put("soGetUser", appUser.getUserId());
			resultMap.put("soBillNumber", soBillNumber);
			resultMap.put("oldStatus","0");
			int row = serviceOrderService.editServiceOrderState(resultMap);
			resultMap.clear();
			log.error("抢单信息：抢单人ID:" + appUser.getUserId() + ",单号：" + soBillNumber + ",row=" + row);
			return returnPageData(resultMap, row > 0, row > 0 ? "0" : "4");
		}catch (Exception e){
			log.error("抢单出错：",e);
		}
		return returnPageData(resultMap, false, "1");
	}

	//已发布订单或已抢订单
	@RequestMapping(value="/issueOrRobServiceOrder", produces="application/json;charset=UTF-8")
	public Object issueOrRobServiceOrder() {
		PageData resultMap = this.getPageData();
		AppUser appUser = this.getSessionAppUser();
		boolean isSuccess = false;
		resultMap.put("status", "0");
		String soBillNumber = resultMap.getString("soBillNumber");
		ServiceOrder serviceOrder = serviceOrderService.getServiceOrderByBillNumber(resultMap);
		//如果订单存在，并且还没被抢
		if (serviceOrder != null && 0 == serviceOrder.getSoStatus()) {
			resultMap.put("so_status", "1");
			resultMap.put("so_get_user", appUser.getUserName());
			resultMap.put("so_bill_number", soBillNumber);
			int row = serviceOrderService.editServiceOrderState(resultMap);
			resultMap.clear();
			isSuccess = row > 0;
		}
		return returnPageData(resultMap, isSuccess, isSuccess ? "0" : "1");
	}

	/**
	 * 返回结果
	 * @param pd 返回的PageData对象
	 * @param isSuccess 是否成功
	 * @param errorFlag 成功或失败标识
	 * @return 返回PageData对象
	 */
	private PageData returnPageData(PageData pd, boolean isSuccess, String errorFlag) {
		pd.put("errorFlag", errorFlag);//0:抢单成功,1:抢单失败
		pd.put("success", isSuccess);
		return pd;
	}
	//我的服务订单信息
	@RequestMapping(value="/queryMyServiceOrder",produces="application/json;charset=UTF-8")
	public Object queryMyServiceOrder() {
        Map<String, Object> resultMap = new HashMap(2);
		PageData pd = this.getPageData();
		int pageNo = pd.getInt("currentPage"), pageSize = pd.getInt("showCount");
		//取得用户名
		AppUser appUser = this.getSessionAppUser();
		String soOrderDate = pd.getString("soOrderDate") == null ? "" : pd.remove("soOrderDate").toString();
		String soServiceDate = pd.getString("soServiceDate") == null ? "" : pd.remove("soServiceDate").toString();
		String soRobDate = pd.getString("soRobDate") == null ? "" : pd.remove("soRobDate").toString();
		String startSuffix = "-01 00:00:00", endSuffix = " 23:59:59";
		int monthLastDay = 0;
		if (StringUtils.hasText(soOrderDate) && soOrderDate.length() < 9) {
            monthLastDay = DateUtil.getLastDayOfMonth(soOrderDate,null);
		    pd.put("soStartOrderDate", soOrderDate + startSuffix);
			pd.put("soEndOrderDate", soOrderDate + "-" + monthLastDay + endSuffix);
		}
		if (StringUtils.hasText(soServiceDate) && soServiceDate.length() < 9) {
            monthLastDay = DateUtil.getLastDayOfMonth(soServiceDate,null);
			pd.put("soStartServiceDate", soServiceDate + startSuffix);
			pd.put("soEndServiceDate", soServiceDate + "-" + monthLastDay + endSuffix);
		}
		if (StringUtils.hasText(soRobDate) && soRobDate.length() < 9) {
            monthLastDay = DateUtil.getLastDayOfMonth(soRobDate,null);
			pd.put("soStartRobDate", soRobDate + startSuffix);
			pd.put("soEndRobDate", soRobDate + "-" + monthLastDay + endSuffix);
		}
		//soType,0:发布订单，1:已抢订单
		String soStatus = pd.getString("soStatus"),soType = pd.getString("soType");
		//如果是待评价
		if ("6".equals(soStatus)) {
			pd.put("soStatus", "2");
			pd.put("notRate", "1".equals(soType) ? "rob" : "issue");
		}else if ("5".equals(soStatus)) {//如果是待服务
			pd.put("soStatus", "1");
		}else {
			pd.put("soStatus", soStatus);
		}
		if (soStatus.contains(",")){
			pd.remove("soStatus");
			pd.put("soStatusStr", soStatus);
		}
		if ("1".equals(soType)) {//如果是查询已抢订单
			pd.put("soGetUser", appUser.getUserId());
			pd.put("soRobDate", pd.remove("soServiceDate"));
			//pd.put("notEqualsStatus","7");
			//5:已取消，6：已过期,7:抢单人删除
			pd.put("notEqualsStatusArray",new String[]{"5","6","7"});
		}else {
			pd.put("soUserId", appUser.getUserId());
            pd.put("notEqualsStatus","3");
		}
		PageInfo myOrderPage = serviceOrderService.pageMyServiceOrder(pageNo,pageSize,pd);
		resultMap.put("status", "0");
		resultMap.put("myPi", myOrderPage);
		return resultMap;
	}
	//我的服务订单信息
	@RequestMapping(value="/myMakeMoney",produces="application/json;charset=UTF-8")
	public Object myMakeMoney() {
		PageData pd = this.getPageData();
		//取得用户名
		AppUser appUser = this.getSessionAppUser();
		pd.put("userName", appUser.getUserId());
		String makeMoney = serviceOrderService.myMakeMoney(pd);
		pd.clear();
		pd.put("status", "0");
		pd.put("totalMakeMoney", makeMoney);
		return pd;
	}
	//编辑服务订单信息
	@RequestMapping(value="/robberDoneOrder",produces="application/json;charset=UTF-8")
	public String robberDoneOrder() {
		PageData pd = this.getPageData();
		String robState;
		try {
			AppUser appUser = this.getSessionAppUser();
            robState = serviceOrderService.robberDoneOrder(appUser.getUserId(),pd);
            pd.clear();
		} catch (Exception e) {
			pd.clear();
            robState = "6";
			log.error(e.toString(),e);
		}
		return robState;
	}
    //发布人完成服务订单操作
    @RequestMapping(value="/issuerDoneOrder",produces="application/json;charset=UTF-8")
    public String issuerDoneOrder() {
        PageData pd = this.getPageData();
        String issuerDoneStatus;
        try {
            AppUser appUser = this.getSessionAppUser();
            issuerDoneStatus = serviceOrderService.issuerDoneOrder(appUser.getUserId(),pd);
        } catch (Exception e) {
            pd.clear();
            issuerDoneStatus = "6";
            log.error(e.toString(),e);
        }
        return issuerDoneStatus;
    }
	//取消服务订单信息
	@RequestMapping(value="/cancelServiceOrder",produces="application/json;charset=UTF-8")
	public String cancelServiceOrder() {
		PageData pd = this.getPageData();
		String cancelState;
		try {
            AppUser cancelUser = getSessionAppUser();
            cancelState = serviceOrderService.cancelServiceOrder(cancelUser,pd);
		} catch (Exception e) {
            cancelState = "6";
			log.error(e.toString(),e);
		}
        pd.clear();
		return cancelState;
	}
	//删除服务订单
	@RequestMapping(value="/deleteOrder",produces="application/json;charset=UTF-8")
	public String deleteOrder(){
		PageData deletePd = this.getPageData();
		String deleteState;
		try {
			deleteState = serviceOrderService.deleteServiceOrder(getSessionAppUser(),deletePd);
		} catch (Exception e) {
			deleteState = "6";
			log.error(e.toString(),e);
		}
		deletePd.clear();
		return deleteState;
	}
	//提交用户评价信息
	@RequestMapping(value="/submitUserRate",produces="application/json;charset=UTF-8")
	public Object submitUserRate() throws Exception {
		PageData pd = this.getPageData();
		String levelNum = pd.getString("levelNum"),userImpression = pd.getString("userImpression"),
		billNo = pd.getString("billNo"),rateText = pd.getString("rateText"), rateIssueOrRob = pd.getString("rateIssueOrRob");
		if (!StringUtils.hasText(levelNum) || !StringUtils.hasText(userImpression) || !StringUtils.hasText(billNo) ||
			!StringUtils.hasText(rateText) || !StringUtils.hasText(rateIssueOrRob)) {
			return "1";
		}
		AppUser user = this.getSessionAppUser();
		String result = serviceOrderService.saveUserRate(pd,user);
		pd.clear();
		return result;
	}

}